<?php

use Swoole\Runtime;

require 'vendor/autoload.php'; // 引入Composer自动加载文件

//set_error_handler(function($errno, $errstr, $errfile, $errline){
//    echo "出错了：$errno, $errstr, $errfile, $errline\n";
//});

define('ROOTPATH', dirname(__FILE__) . '/');
define('APPPATH', ROOTPATH . 'app/');
define('RUNTIMEPATH', ROOTPATH . 'runtime/');
define('LOGPATH', RUNTIMEPATH . 'log/');
define('CACHEPATH', RUNTIMEPATH . 'cache/');
define('TABLEPATH', RUNTIMEPATH . 'table/');
define('PUBLICPATH', ROOTPATH . 'public/');

//包含配置文件
$CFG = require_once dirname(__FILE__) . '/config.inc.php';

//设置时区
date_default_timezone_set('Asia/Shanghai');
//引入自定义函数文件
require_once APPPATH . 'core/functions.inc.php';

Runtime::enableCoroutine();

$http = new Swoole\Http\Server($CFG['base']['host'], $CFG['base']['port']);
$http->set([
    "worker_num" => $CFG['base']['worker_num'],
    "log_file" => LOGPATH . 'swoole.log',
    "log_level" => $CFG['base']['log_level'],
    "daemonize" => $CFG['base']['daemonize'],
]);

$http->on('start', function ($server) {
    global $CFG;
    echo "Swoole http server is started at http://{$CFG['base']['host']}:{$CFG['base']['port']}\n";
});

$http->on('WorkerStart', function ($server, $worker_id) {
    echo "worker: {$worker_id} started\n";
});

$http->on('request', function ($request, $response) {
    global $CFG;
    try {
        $response->header('Content-Type', 'application/json;charset=utf-8');

        $route = explode('/', trim($request->server['request_uri'], '/'));
        $route = array_map('trim', $route);
        $route = array_map('strtolower', $route);

        if (!(isset($route[0]) && $route[0])) {
            $route[0] = 'index';
        }

        if (!(isset($route[1]) && $route[1])) {
            $route[1] = 'index';
        }

        //调用app的控制器
        $class = APPPATH . 'controllers/' . ucfirst($route[0]) . 'Controller.php';
        if (!file_exists($class)) {
            $response->end(\msg(0, "Controller does not exist"));
            return;
        }

        //排除一些魔术方法
        $deny_list = array('_before', '_after', '__construct', '__destruct', '__call', '__callStatic', '__get', '__set', '__isset', '__unset', '__sleep', '__wakeup', '__toString', '__invoke', '__set_state', '__clone');
        if (in_array($route[1], $deny_list)) {
            $response->end(\msg(0, "Action does not exist"));
            return;
        }

        $classpath = "\\Faye\controllers\\" . ucfirst($route[0]) . "Controller";
        $object = new $classpath();
        $object->CONTROLLER = $route[0];
        $object->ACTION = $route[1];
        $object->CFG = $CFG;

        //判断方法是否存在
        if (!method_exists($object, $route[1])) {
            $response->end(\msg(0, "Action does not exist"));
            return;
        }

        //利用反射类判断方法是否可以调用
        $ref = new ReflectionMethod($object, $route[1]);
        if (!$ref->isPublic()) {
            $response->end(\msg(0, "Action does not exist"));
            return;
        }

        //调用类下的方法
        $func = $route[1];
        $data = $object->$func($request, $response);
        $response->end($data);
    } catch (Exception $e) {
        echo $e->getMessage() . "\n";
        $response->end(\msg(0, "The system has encountered an error"));
    }

});
$http->start();


